package calpi.database;

import calpi.Usuario;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 *
 * @author Sem iNick
 */
public class UsuariosConnector extends DataBaseConnector<Usuario> {


    /**
     * Arquivo padrão para os dados dos usuários (users.rdb)
     */
    public static final File DEFAULT_FILE = new File("users.rdb");

    private DataInputStream inStream;
    private DataOutputStream outStream;

    /**
     * Cria uma conexão com os dados dos usuários usandos um arquivo de entrada e
     * um de saída
     * @param fileIn Objeto relacionado ao arquivo que será usado como
     * entrada de dados
     * @param fileOut Objeto relacionada ao arquivo que será usada como saída
     * de dados
     * @throws FileNotFoundException Se algum arquivo não existir e não puder
     * ser criado
     * @throws IOException Se ocorrer algum error E/S
     */
    public UsuariosConnector(File fileIn, File fileOut)
            throws FileNotFoundException, IOException {

        super(fileIn, fileOut);
        inStream = new DataInputStream(new FileInputStream(fileIn));
        outStream = new DataOutputStream(new FileOutputStream(fileOut, true));
    }

    /**
     * Cria uma conexão com os dados dos usuários usando o caminho para um arquivo
     * de entrada e outro de saída
     * @param fileIn Caminho para o arquivo de entrada
     * @param fileOut Caminho para o arquivo de saída
     * @throws FileNotFoundException Se algum arquivo não existir e não puder
     * ser criado
     * @throws IOException Se ocorrer algum erro E/S
     */
    public UsuariosConnector(String fileIn, String fileOut)
            throws FileNotFoundException, IOException {

        this(new File(fileIn), new File(fileOut));
    }

    /**
     * Cria uma conexão com os dados dos usuários usando um arquivo com entrada e
     * saída de dados
     * @param file Objeto relacionado com o arquivo que será usado como entrada
     * e saída
     * @throws FileNotFoundException Se o arquivo não existir e não puder ser
     * criado
     * @throws IOException Se ocorrer algum erro E/S
     */
    public UsuariosConnector(File file) throws FileNotFoundException, IOException {

        this(file, file);
    }

    /**
     * Cria uma conexão com os dados dos usuários usando um caminho para um arquivo
     * que será usado com entrada e saída de dados
     * @param file Caminho onde se encontra o arquivo que será usado
     * @throws FileNotFoundException Se o arquivo não existir e não puder ser
     * criado
     * @throws IOException Se ocorrer algum erro E/S
     */
    public UsuariosConnector(String file) throws FileNotFoundException, IOException {

        this(new File(file));
    }

    /**
     * Cria uma conexão com os dados dos usuários usando o arquivo padrão como
     * entrada e saída
     * @throws FileNotFoundException Se o arquivo não existir e não puder ser
     * criado
     * @throws IOException Se ocorrer algum error E/S
     * @see UsuariosConnector#DEFAULT_FILE
     */
    public UsuariosConnector() throws FileNotFoundException, IOException {

        this(DEFAULT_FILE);
    }

    @Override
    protected void finalize() throws Throwable {

        closeConnection();
    }

    @Override
    public void readFully() throws IOException {
        
        LinkedList<Usuario> buffer = new LinkedList<Usuario>();
        try {

            while (true) {

                buffer.add(new Usuario(inStream.readUTF(), inStream.readUTF(),
                            inStream.readUTF()));
            }
        } catch (EOFException eofe) {

            //Chegamos ao fim do arquivo \o/
        }

        bufferIn = new Usuario[buffer.size()];
        bufferOut = new ArrayList<Usuario>(buffer);
    }

    @Override
    public void writeBuffer() throws IOException {

        for (Usuario user : bufferOut) {

            outStream.writeUTF(user.getNome());
            outStream.writeUTF(user.getLogin());
            outStream.writeUTF(user.getSenha());
        }

        bufferIn = new Usuario[bufferOut.size()];
        bufferOut.toArray(bufferIn);
    }

    @Override
    public void closeConnection() throws Throwable {

        if (inStream != null) {

            inStream.close();
        }

        if (outStream != null) {

            outStream.close();
        }
    }

}
